<template>
  <div class="mainBody">
    <div class="content">
      <div class="main-formula">
        <div class="left-box">
          <div class="area-title">{{ $t('指标类别') }}</div>
          <ul>
            <li class="pcw-li" :class="zhibiao === '1' ? 'on' : ''" @click="loadKeyDetails('balance_sheet','1')">{{ $t('资产负债') }}</li>
            <li class="pcw-li" :class="zhibiao === '2' ? 'on' : ''" @click="loadKeyDetails('income_sheet','2')">{{ $t('利润及利润分配') }}</li>
            <li class="pcw-li" :class="zhibiao === '3' ? 'on' : ''" @click="loadKeyDetails('cash_flow_sheet','3')">{{ $t('现金流量') }}</li>
          </ul>
        </div>
        <div v-loading="loading" class="right-box">
          <div class="area-title" style="padding: 5px 5px 0 15px;">
            <el-input v-model="subjectSearchVal" size="mini" :placeholder="$t('选择科目')" clearable @input="querySearch" />
          </div>
          <!-- <div class="area-title">{{ $t('选择指标') }}</div> -->
          <template v-if="subjects && subjects.length > 0">
            <ul>
              <li v-for="sub in subjects" v-show="sub.keyName" :key="sub.id" class="pcw-li" :class="zhibiaosub === sub.id ? 'on' : ''" @click="addItem(sub.id, 'obj')">{{ sub.keyName }}</li>
            </ul>
          </template>
          <div v-else class="empty" style="color: #adadad;text-align: center;margin: 50px 0;">
            {{ $t('请选择左侧指标类别') }}
          </div>
        </div>
      </div>
      <div class="formul-area">
        <div class="Symbol">
          <span v-for="item in operatorList" :key="item.id" class="symbol-span" @click="addItem(item.id, 'plain')">{{ item.name }}</span>
          <el-radio-group v-if="showDate" v-model="cycleDate" size="mini">
            <el-radio-button :label="3" @click.native.prevent="radioHandle('3')">{{ $t('上一季') }}</el-radio-button>
            <el-radio-button :label="4" @click.native.prevent="radioHandle('4')">{{ $t('上年同期') }}</el-radio-button>
            <el-radio-button :label="5" @click.native.prevent="radioHandle('5')">{{ $t('上年年末') }}</el-radio-button>
            <el-radio-button :label="1" @click.native.prevent="radioHandle('1')">{{ $t('上一期') }}</el-radio-button>
            <div class="block-empty" />
            <el-tooltip class="item" effect="light" content="" placement="top-start">
              <div slot="content">1.一季0.25,二季0.5,三季0.75,四季达顶1,稳步上升显趋势<br>2.若营业收入为分母，系数应用乘法；反之，则行除法</div>
              <el-radio-button :label="10" @click.native.prevent="radioHandle('10')">{{ $t('报告期系数') }}</el-radio-button>
            </el-tooltip>
            <el-tooltip class="item" effect="light" content="" placement="top-start">
              <div slot="content">1.近两季度的平均值 如:((应收账款(上一期)+应收账款(本次))/2)</div>

              <el-radio-button :label="11" @click.native.prevent="radioHandle('11')">{{ $t('近两期平均值') }}</el-radio-button>
            </el-tooltip>
          </el-radio-group>
        </div>
        <div id="formulaView" ref="formulaView" class="formulaView" @click.stop="recordPosition()">
          <div
            v-for="(item, index) in formulaList"
            :key="index"
            class="content-item"
            @click.stop="recordPosition(index)"
          >
            <div v-if="item.type === 'num'" class="num">
              &zwj;{{ item.value }}
            </div>
            <div v-else-if="item.type === 'plain'" class="plain">
              &zwj;{{ item.value }}
            </div>
            <div v-else-if="item.type === 'obj'" class="obj">
              &zwj;{{ item.value }}
            </div>

            <!--光标-->
            <div v-if="item.cursor" class="cursor" />
          </div>
        </div>
      </div>
    </div>
    <div slot="footer" class="dialog-footer" style="text-align: right;margin-top: 20px;">
      <!--保存，保存并启动流程，取消 三个按钮-->
      <el-button @click="cancel">{{ $t("取消") }}</el-button>
      <el-button @click="resetFormula">{{ $t("重置") }}</el-button>
      <el-button v-hasPermi="['company:pcw:edit']" type="primary" @click="confirmData">{{ $t("确定") }}</el-button>
    </div>
  </div>
</template>

<script>
    import { listPcwTempSubject } from '@/api/company/pcw/pcwTempSubject'
    import { listPcwTempSysSubject } from '@/api/company/pcw/pcwTempSysSubject'
    import { Notification } from 'element-ui'
    export default {
      props: {
        companyId: {
          type: String,
          default: () => ''
        },
        typeId: {
          type: String,
          default: () => ''
        },
        formula: {
          type: Object,
          default: () => {}
        },
        showDate: {
          type: Boolean,
          default: () => true
        },
         isSysTemp: {
          type: Boolean,
          default: () => false
        }
      },
        data() {
            return {
                loading: false,
                subjects: {}, // 关键指标基础科目
                queryParams: {
                  tableType: '',
                  companyId: this.companyId,
                  typeId: this.$route.query.typeId || this.typeId
                },
                zhibiao: '', // 一级指标
                zhibiaosub: '', // 二级指标
                formulaName: '', // 公式name
                formulaCode: '', // 公式code
                cycleDate: '', // 区分上一季、上一年
                qubie: '', // 区别上一公式结尾是数字还是指标还是操作符
                formulaList: [],
                cacheSubjects: [],
                subjectSearchVal: undefined,
                operatorList: [ // 运算符
                  { name: '+', id: '+' },
                  { name: '-', id: '-' },
                  { name: '×', id: '*' },
                  { name: '÷', id: '/' },
                  { name: '()', id: '()' },
                  { name: '√()', id: '√()' }
                ]
            }
        },
        watch: {
          formulaList() {
              this.parsingFormula()
          },
          formula: {
            handler(val) {
              this.resetFormula()
              this.$nextTick(() => {
                this.formulaList = JSON.parse(JSON.stringify(val.formulaList)) || []
              })
            },
            deep: true,
            immediate: true
          }
        },
        created() {
        },
        mounted() {
          this.resetFormula()
          this.keyDown()
          // 监听鼠标事件
          this.$nextTick(() => {
              document.addEventListener('click', this.formulaBlur)
          })
        },
        destroyed() {
          // 取消键盘监听事件
          document.onkeydown = null
          // 移除监听事件
          document.removeEventListener('click', this.formulaBlur)
        },
        methods: {
          // 根据类型获取基础科目详情
          loadKeyDetails(table, zhibiao) {
            this.loading = true
            this.queryParams.tableType = table
            this.zhibiao = zhibiao
            if (this.isSysTemp) { // 系统模板的接口
                  this.queryParams.belongsTable = table
                  listPcwTempSysSubject(this.queryParams).then(res => {
                    this.subjects = res.rows
                    this.cacheSubjects = res.rows
                    this.loading = false
                  })
            } else {
               listPcwTempSubject(this.queryParams).then(res => {
                  this.subjects = res.rows
                  this.cacheSubjects = res.rows
                  this.loading = false
              })
            }
          },
          // 展示公式错误信息
          errorMsg() {
            Notification.error({
              title: this.$t('此操作会导致公式错误！')
            })
          },
          // 重置按钮
          resetFormula() {
            this.subjects = []
            this.formulaList = []
            this.formulaName = ''
            this.formulaCode = ''
            this.cycleDate = ''
            this.qubie = ''
            this.zhibiao = ''
          },
          // 取消按钮
          cancel() {
              this.$parent.$parent.formOpen = false
          },
          /** 提交按钮 */
          confirmData: function() {
            if (this.formulaName === '') {
              Notification.error({
                title: this.$t('请选择公式！')
              })
            } else {
              // 校验公式是否正确
              if (!this.isEmpty(this.formulaList)) {
                var checkFormula = JSON.parse(JSON.stringify(this.formulaList))
                checkFormula.forEach(item => {
                  if (item.type === 'obj') {
                    item.value = 1
                  }
                })
                // 将数组中的所有值放入数组
                var simulationFormula = []
                checkFormula.forEach(item => {
                  simulationFormula.push(item.value)
                })
                // 将数值转成字符串,如果不报错.说明公式合理
                try {
                  var str = simulationFormula.join(' ').replace(/\s/g, '')
                  // var eval1 = eval(simulationFormula.join(' '))
                  // eslint-disable-next-line no-eval
                  var eval1 = eval(str)
                  console.log(eval1)
                  this.$parent.$parent.addFormula(this.formulaName, this.formulaCode, this.formulaList)
                  this.$parent.$parent.formOpen = false
                } catch (e) {
                  console.error(e)
                  this.msgError(this.$t('公式有误，请检查！'))
                }
              }
            }
          },
          radioHandle(e) { // 可取消选中
              e === this.cycleDate ? this.cycleDate = '' : this.cycleDate = e
              if (e === '10') {
                this.addItem('btn', 'btn', '10')
                this.cycleDate = false
              }
          },
          // 点选时记录光标位置
          recordPosition(index) {
            // console.log(index)
              if (this.formulaList && this.formulaList.length > 0) {
                  this.formulaList = this.formulaList.map((item, itemIndex) => {
                      item.cursor = false
                      if (index > -1 && index === itemIndex) {
                          item.cursor = true
                      } else if ((index !== 0 && !index) && itemIndex === (this.formulaList.length - 1)) {
                          item.cursor = true
                      }
                      return item
                  })
              } else {
                  this.formulaList = [
                      {
                          cursor: true,
                          type: 'placeholder',
                          value: ''
                      }
                  ]
              }
              // this.$forceUpdate();
          },
          // 失去焦点
          formulaBlur() {
              this.formulaList = this.formulaList?.map(item => {
                  item.cursor = false
                  return item
              })
          },
          /**
           * 添加字段
           * type obj 字段  num 数字 plain符号
           * place 是否修改光标位置
           */
          addItem(val, type, btnType = '1', place = true) {
              if (!val) return false
              // TODO 校验公式
              const that = this
              // 插入括号
              if (type === 'plain' && val === '()') {
                  val = '('
                  setTimeout(() => {
                      that.addItem(')', type, false)
                  }, 50)
              }
              if (type === 'plain' && val === '√()') {
                  val = '√('
                  setTimeout(() => {
                      that.addItem(')', type, false)
                  }, 50)
              }

              const data = {
                  value: '',
                  key: val,
                  type: type
              }

              if (btnType === '10') {
                  val = ''
                 const btnData = { 'value': '报告期系数', 'key': 'factor', 'type': 'obj', 'cursor': false }
                this.formulaList.push(btnData)
              }
              if (type === 'obj') {
                  this.zhibiaosub = val
                  // 获取数据 为 value 赋值
                  var obj = this.subjects?.find(item => item.id === val)
                  var code = obj.keyCode
                  var name = obj.keyName

                  if (this.cycleDate === '11') {
                      // (应收账款(上一期)+应收账款(本次)
                      data.value = name + ' (近两期平均值)'
                  } else {
                    data.value = name + this.changeName(this.cycleDate)
                  }
                  if (this.cycleDate === '') {
                    if (this.zhibiao === '1') {
                      data.key = '#1BS{thisDate.' + code + '}'
                    } else if (this.zhibiao === '2') {
                      data.key = '#1PL{thisDate.' + code + '}'
                    } else if (this.zhibiao === '3') {
                      data.key = '#1CF{thisDate.' + code + '}'
                    }
                  } else {
                    if (this.zhibiao === '1') {
                      data.key = '#1BS{' + this.changeZb(this.cycleDate, code) + '}'
                    } else if (this.zhibiao === '2') {
                      data.key = '#1PL{' + this.changeZb(this.cycleDate, code) + '}'
                    } else if (this.zhibiao === '3') {
                      data.key = '#1CF{' + this.changeZb(this.cycleDate, code) + '}'
                    } else if (this.zhibiao === '11') {
                      data.key = '#1CF{' + this.changeZb(this.cycleDate, code) + '}'
                    }
                  }
              } else {
                  data.value = val
              }
              if (this.formulaList && this.formulaList.length > 0) {
                  const length = this.formulaList.length
                  for (let i = 0; i < length; i++) {
                      // 查找光标位置 如果光标位置为空 则在最后添加
                      if (this.formulaList[i].cursor) {
                          this.formulaList.splice(i + 1, 0, data)
                          place && this.recordPosition(i + 1)
                          break
                      } else if (i === (this.formulaList.length - 1)) {
                          this.formulaList.push(data)
                          this.recordPosition(this.formulaList.length - 1)
                      }
                  }
              } else {
                  if (!this.formulaList) {
                      this.formulaList = []
                  }
                  this.formulaList.push(data)
                  this.recordPosition(this.formulaList.length - 1)
              }
          },
          // 改变公式code
          changeZb(cycleDate, code) {
            if (cycleDate === '1') {
              return 'lastDate.' + code
            } else if (cycleDate === '2') {
              return 'lastMonth.' + code
            } else if (cycleDate === '3') {
              return 'lastQuarter.' + code
            } else if (cycleDate === '4') {
              return 'lastYear.' + code
            } else if (cycleDate === '5') {
                // 上年年末
                return 'endOfYear.' + code
            } else if (cycleDate === '10') {
                // 报告期系数
                return 'factor'
            } else if (cycleDate === '11') {
                // 近两期平均值
                return 'latelyPeriodAVG.' + code
            }
          },
          // 改变展示公式名称
          changeName(cycleDate) {
            if (cycleDate === '1') {
              return this.$t('(上一期)')
            } else if (cycleDate === '2') {
              return this.$t('(上一月)')
            } else if (cycleDate === '3') {
              return this.$t('(上一季)')
            } else if (cycleDate === '4') {
              return this.$t('(上年同期)')
            } else if (cycleDate === '5') {
              return this.$t('(上年年末)')
            } else if (cycleDate === '10') {
              return this.$t('报告期系数')
            } else {
              return this.$t('(本次)')
            }
          },
          // 清除全部
          clearAll() {
              this.formulaList = []
              const that = this
              setTimeout(() => {
                  that.recordPosition()
              }, 100)
          },

          // 删除
          deleteItem(type) {
              const arr = JSON.parse(JSON.stringify(this.formulaList)); let index = null
              const length = arr?.length
              for (let i = 0; i < length; i++) {
                  if (arr[i].cursor) {
                      index = i
                      if (type === 'del') {
                          index = i + 1
                      }
                      if (index > -1) {
                          this.formulaList.splice(index, 1)
                          if (type === 'del') {
                              console.log(1)
                          } else {
                              this.recordPosition(index - 1)
                          }
                          this.$forceUpdate()
                      }
                      break
                  }
              }
          },

          // 键盘输入
          keyDown() {
            // todo
            // 事件对象兼容
            document.onkeydown = (event) => {
              // eslint-disable-next-line no-caller
              const e = event || window.event || arguments.callee.caller.arguments[0]
              console.log('键盘按键==', e, e.keyCode)

              let index = null
              this.formulaList?.find((item, itemIndex) => {
                  if (item.cursor) {
                      index = itemIndex
                  }
              })
              // 左右移动键控制光标位置
              if (e && [37, 39].includes(e.keyCode)) {
                  if (e.keyCode === 37) { index = index - 1 } else { index = index + 1 }
                  if (index > -1 && index < this.formulaList.length) {
                      this.recordPosition(index)
                  }
              } else if (e && e.keyCode === 8) {
                  // Backspace 键 删除前面的值
                  this.deleteItem()
              } else if (e && [107, 109, 106, 111].includes(e.keyCode)) {
                  // 运算符列表
                  this.addItem(e.key, 'plain')
              } else if (e && e.shiftKey && [48, 57].includes(e.keyCode)) {
                  // 括号
                  if (e.keyCode === 48) e.key = ')'
                  if (e.keyCode === 57) e.key = '('
                  this.addItem(e.key, 'plain')
              } else if (e && e.keyCode === 46) {
                  // delete键删除光标后面的值
                  this.deleteItem('del')
              } else {
                  document.returnValue = false
                  var tt = /^[0-9]+\.{0,1}[0-9]{0,}$/ // 能输入正数
                  if (tt.test(e.key)) {
                      // 输入为数字 插入数字
                      this.addItem(e.key, 'num')
                  }
              }
            }
          },

          /**
           * 公式转为字符串
           * **/
          parsingFormula() {
            let name = ''
            let code = ''
            var arr = Object.assign([], this.formulaList)
            arr?.map(item => {
                if (item.value) {
                  name += item.value
                }
                if (item.key) {
                  code += item.key
                }
            })
            this.formulaName = name
            this.formulaCode = code
          },
          querySearch() {
            console.log('this.cacheSubjects', this.cacheSubjects)
            // console.log(this.subjectSearchVal)
            if (this.subjectSearchVal === '') {
              this.subjects = this.cacheSubjects
            } else {
              console.log('this.cacheSubjects', this.cacheSubjects)
              const subjects = this.cacheSubjects.filter(item => item.keyName.toString().indexOf(this.subjectSearchVal) >= 0)
              this.subjects = subjects
            }
          }
        }
    }
</script>
<style lang="scss" scoped>
#formulaView {
  height: 120px;
  font-size: 12px;
  overflow-y: auto;

  .content-item {
      position: relative;
      cursor: text;
      user-select: none;
      display: inline-flex;
      align-items: center;
      >div{
        margin: 0 5px 5px 0;
      }

      .cursor {
          height: 13px;
          width: 1px;
          background: #333;
          animation: defaultCursor 1s steps(2) infinite;
          position: absolute;
          right: -3px;
      }

      .obj {
          padding: 3px 5px;
          background: #f1f1f1;
          border-radius: 3px;
          font-size: 11px;
      }
      .plain{
        padding: 3px 1px;
        font-size: 11px;
      }

      .num {
          color: #000;
          background: #fff;
          padding: 0 1px 0 0;
      }
  }
}

@keyframes defaultCursor {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}
.el-radio-group /deep/.block-empty{
  padding-left: 10px;
  display: inline-block;
  padding-right: 10px;
  border-right: 1px solid;
  height: 20px;
  margin-bottom: -10px;
  color: #DCDFE6
}
</style>
